#include "FTPTools.h"

FTPTools::FTPTools(const std::string& _ftpUrl, const std::string& _ftpUserName
	, const std::string& _ftpPassword)
	: ftpUrl_(_ftpUrl)
	, ftpUserName_(_ftpUserName)
	, ftpPassword_(_ftpPassword)
{
}

FTPTools::~FTPTools()
{
}

bool FTPTools::UploadFile(const std::string& _ftpFilePath, const std::string& _localFilePath)
{
	CURL* curl;
	CURLcode res;

	curl_global_init(CURL_GLOBAL_DEFAULT);
	curl = curl_easy_init();

	// 将ftp地址和文件路径拼接起来
	std::string ftpFilePath = ftpUrl_ + "/" + _ftpFilePath;

	if (curl)
	{
		// 设置 FTP 上传地址
		curl_easy_setopt(curl, CURLOPT_URL, ftpFilePath.c_str());

		// 设置用户名和密码
		curl_easy_setopt(curl, CURLOPT_USERNAME, ftpUserName_.c_str());
		curl_easy_setopt(curl, CURLOPT_PASSWORD, ftpPassword_.c_str());

		// 启用上传
		curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);

		// 可自动创建不存在的目录
		curl_easy_setopt(curl, CURLOPT_FTP_CREATE_MISSING_DIRS, 1L);

		// 本地文件路径
		FILE* fp = fopen(_localFilePath.c_str(), "rb");
		if (fp)
		{
			curl_easy_setopt(curl, CURLOPT_READDATA, fp);

			curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION);

			res = curl_easy_perform(curl);

			fclose(fp);

			if (res != CURLE_OK)
			{
				std::cerr << "上传失败: " << curl_easy_strerror(res) << std::endl;
				
				curl_easy_cleanup(curl);

				curl_global_cleanup();

				return false;
			}
		}
		else 
		{
			std::cerr << "无法打开本地文件: " << _localFilePath << std::endl;

			curl_easy_cleanup(curl);

			curl_global_cleanup();

			return false;
		}

		curl_easy_cleanup(curl);
	}

	curl_global_cleanup();
}

// @brief 回调函数，用于写入下载的数据
size_t WriteData(void* _ptr, size_t _size, size_t _nmemb, FILE* _stream)
{
	size_t written = fwrite(_ptr, _size, _nmemb, _stream);
	return written;
}

bool FTPTools::DownloadFile(const std::string& _ftpFilePath, const std::string& _localFilePath)
{
	CURL* curl;
	CURLcode res;
	FILE* fp;

	curl_global_init(CURL_GLOBAL_DEFAULT);

	curl = curl_easy_init();

	// 将ftp地址和文件路径拼接起来
	std::string ftpFilePath = ftpUrl_ + "/" + _ftpFilePath;

	if (curl)
	{
		fp = fopen(_localFilePath.c_str(), "wb");

		curl_easy_setopt(curl, CURLOPT_URL, ftpFilePath.c_str());
		curl_easy_setopt(curl, CURLOPT_USERNAME, ftpUserName_.c_str());
		curl_easy_setopt(curl, CURLOPT_PASSWORD, ftpPassword_.c_str());

		curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteData);
		curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);

		res = curl_easy_perform(curl);

		fclose(fp);

		if (res != CURLE_OK)
		{
			std::cerr << "下载失败: " << curl_easy_strerror(res) << std::endl;

			curl_easy_cleanup(curl);

			curl_global_cleanup();

			return false;
		}

		curl_easy_cleanup(curl);
	}

	curl_global_cleanup();

	return true;
}

// 回调函数，用于处理获取到的数据
size_t writeCallback(char* ptr, size_t size, size_t nmemb, void* userdata) 
{
	std::string* response = static_cast<std::string*>(userdata);
	response->append(ptr, size * nmemb);
	return size * nmemb;
}

void FTPTools::GetAllFileList(std::vector<std::string>& _result, const std::string& _dirPath)
{
	CURL* curl;
	CURLcode res;

	curl_global_init(CURL_GLOBAL_DEFAULT);
	curl = curl_easy_init();

	if (curl) 
	{
		std::string response;

		std::string path = ftpUrl_ + _dirPath;

		// 设置 URL
		curl_easy_setopt(curl, CURLOPT_URL, path.c_str());
		curl_easy_setopt(curl, CURLOPT_USERNAME, ftpUserName_.c_str());
		curl_easy_setopt(curl, CURLOPT_PASSWORD, ftpPassword_.c_str());

		// 设置回调函数来处理获取到的数据
		curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeCallback);
		curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);

		// 启用 FTP 列表模式
		curl_easy_setopt(curl, CURLOPT_DIRLISTONLY, 1L);

		res = curl_easy_perform(curl);

		if (res == CURLE_OK)
		{
			// 解析响应获取文件和路径信息
			std::string line;
			std::istringstream iss(response);
			while (std::getline(iss, line))
			{
				line = line.substr(0, line.size() - 1);
				GetAllFileList(_result, _dirPath + line + "/");

				_result.emplace_back(path + line + "/");
				std::cout << path + line + "/" << std::endl;
			}
		}

		curl_easy_cleanup(curl);
	}

	curl_global_cleanup();
}
